package com.oahzuw;

import com.oahzuw.utils.Heroes;
import javafx.application.Application;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.ListView;
import javafx.scene.control.TextArea;
import javafx.scene.image.Image;
import javafx.scene.layout.FlowPane;
import javafx.stage.Stage;
import org.joda.time.Duration;
import org.joda.time.format.PeriodFormatter;
import org.joda.time.format.PeriodFormatterBuilder;
import skadistats.clarity.model.CombatLogEntry;
import skadistats.clarity.processor.gameevents.OnCombatLogEntry;
import skadistats.clarity.processor.runner.SimpleRunner;
import skadistats.clarity.source.MappedFileSource;

import java.io.IOException;
import java.util.*;

public class Main extends Application {

    /**
     * dem输出相关变量
     */
    private TextArea textArea;
    private Map<String, Integer> map = new TreeMap<>();
    private Map<String, List<String>> mvpHero = new TreeMap<>();
    private List<String> roshanList = new ArrayList<>();
    private Boolean endFlag = false;



    @Override
    public void start(Stage primaryStage) throws Exception {
        Parent root = FXMLLoader.load(getClass().getResource("Controller.fxml"));
        // 禁止改变窗口大小
        primaryStage.setResizable(false);
        primaryStage.setTitle("Dota2回放文件解析工具，快速定位英雄击杀瞬间，方便制作精品视频，工具更新请关注公众号：神秘商店怎么走");
        primaryStage.setScene(new Scene(root, 800, 600));

        // 设置图标
        primaryStage.getIcons().add(new Image(getClass().getResourceAsStream("dota2.png")));

        // 绑定事件
        this.textArea = (TextArea) root.lookup("#resultTextArea");
        textArea.setStyle("-fx-font-size:18");

        ListView listView = (ListView) root.lookup("#fileListView");
        listView.getSelectionModel().selectedItemProperty().addListener(new ChangeListener() {
            @Override
            public void changed(ObservableValue observable, Object oldValue, Object newValue) {
                // 点击后先把之前的数据清空开始
                endFlag = false;
                textArea.setText("");
                choseTime = 0L;
                map.clear();
                mvpHero.clear();
                roshanList.clear();
                // 数据清空结束
                String filePath = Controller.map.get(newValue.toString());
                try {
                    new SimpleRunner(new MappedFileSource(filePath)).runWith(this);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            public void printKillInfo() {
                // 多次打印结束日志，使得标记标识
                if (endFlag) {
                    return;
                }
                endFlag = true;
                textArea.appendText("=======================================\n");
                textArea.appendText("击杀排行：\n");
                // 排序
                //这里将map.entrySet()转换成list
                List<Map.Entry<String, Integer>> list = new ArrayList<Map.Entry<String, Integer>>(map.entrySet());
                //然后通过比较器来实现排序
                Collections.sort(list, new Comparator<Map.Entry<String, Integer>>() {
                    //升序排序
                    @Override
                    public int compare(Map.Entry<String, Integer> o1, Map.Entry<String, Integer> o2) {
                        return o2.getValue().compareTo(o1.getValue());
                    }
                });
                String table = "";
                Integer total = 0;
                for (Map.Entry<String, Integer> mapping : list) {
                    String key = mapping.getKey();
                    table = key.length() == 2 ? "\t\t\t" : key.length() == 5 ? "\t" : "\t\t";
                    total += mapping.getValue();
                    textArea.appendText(key + table + "击杀个数为：\t" + mapping.getValue() + "\n");
                }

                textArea.appendText("............\n");
                textArea.appendText("总击杀数：" + total + "\n");
                textArea.appendText("............\n");
                textArea.appendText("MVP Show Time:\n");
                for (String str : mvpHero.get(list.get(0).getKey())) {
                    textArea.appendText(str);
                }
                textArea.appendText("\n肉山被击杀情况:\n");
                if (roshanList.size() < 1) {
                    textArea.appendText("......本场对战没有击杀过肉山！");
                }
                for (String str : roshanList) {
                    textArea.appendText(str);
                }
            }

            @OnCombatLogEntry
            public void onCombatLogEntry(CombatLogEntry cle) {
                String gameTime = "[" + GAMETIME_FORMATTER.print(Duration.millis((long) (1000.0f * cle.getTimestamp()) - choseTime).toPeriod()) + "]";
                switch (cle.getType()) {
                    case DOTA_COMBATLOG_GAME_STATE:
                        // 游戏开始
                        if (cle.getValue() == 5) {
                            choseTime = (long) cle.getTimestamp() * 1000;
                        }
                        // 游戏结束
                        if (cle.getValue() == 7 || cle.getValue() == 6) {
                            printKillInfo();
                        }
                        break;
                    case DOTA_COMBATLOG_DEATH:
                        // 英雄击杀
                        if (cle.getTargetName().startsWith("npc_dota_hero")) {
                            String attackerName = Heroes.getHeroes().getOrDefault(cle.getAttackerName(), cle.getAttackerName());
                            String table = "";
                            table = attackerName.length() == 2 ? "\t\t\t" : attackerName.length() == 5 ? "\t" : "\t\t";
                            String text = gameTime + "  "
                                    + attackerName
                                    + table + "击杀\t\t"
                                    + Heroes.getHeroes().get(cle.getTargetName()) + "\n";

                            if (map.containsKey(attackerName)) {
                                List<String> list = mvpHero.get(attackerName);
                                list.add(text);
                                mvpHero.put(attackerName, list);
                                map.put(attackerName, map.get(attackerName) + 1);
                            } else {
                                map.put(attackerName, 1);
                                List<String> list = new ArrayList<>();
                                list.add(text);
                                mvpHero.put(attackerName, list);
                            }
                            textArea.appendText(text);
                        }
                        // 击杀肉山
                        if (cle.getTargetName().equals("npc_dota_roshan")) {
                            String attackerName = Heroes.getHeroes().getOrDefault(cle.getAttackerName(), cle.getAttackerName());
                            String table = "";
                            table = attackerName.length() == 2 ? "\t\t\t" : attackerName.length() == 5 ? "\t" : "\t\t";
                            String text = gameTime + "  "
                                    + attackerName
                                    + table + "击杀\t\t"
                                    + Heroes.getHeroes().get(cle.getTargetName()) + "\n";
                            roshanList.add(text);
                        }
                        break;
                    default:
                        break;
                }
            }
        });

        primaryStage.show();


    }

    private Long choseTime = 0L;


    public static void main(String[] args) {
        launch(args);
    }


    private final PeriodFormatter GAMETIME_FORMATTER = new PeriodFormatterBuilder()
            .minimumPrintedDigits(2)
            .printZeroAlways()
            .appendHours()
            .appendLiteral(":")
            .appendMinutes()
            .appendLiteral(":")
            .appendSeconds()
            .appendLiteral(".")
            .appendMillis3Digit()
            .toFormatter();
}
